
#ifndef __GEOMETRY_H__
#define __GEOMETRY_H__

#include "Mesh.h"
#include "Texture.h"

// Parent Class
class Entity;
// Derived Classes
class SubdivisionGeom;
class BillboardGeom;

// Enum
enum Level { Hi = -1, Med = 0, Lo = 1 };

class Geometry
{
public:

	// Constructor
	Geometry(Entity *_parent);

	// Destructor
	~Geometry();

	// Returns the parent
	Entity *Parent() const { return parent; }

	// Renders the geometry
	void Render();

	// Clears the geometry
	virtual void Clear();

	// Tries to calculate texture coordinates
	void CalculateTextureCoordinates(float scale, TexCoordType type);

	// Merges the duplicated vertices & corrects the quads & triangles
	void MergeDuplicateVertices();

	// Calculates the vertex normals from the faces
	void CalculateVertexNormals();

	// Loads a texture
	void LoadTexture(TCHAR *fileName);
	void LoadTexture(TCHAR *fileName, Color alpha);

	// File Input / Output
	virtual void Write(FileStream &file);
	virtual void Read(FileStream &file);

	// Array of normals to be rendered
	static vector<Line> normals;
	static bool updateNormals;
	static bool updateBillboards;

	// Returns type of Geometry
	bool IsSubdivisionGeom() const { return isSubdivisionGeom; }
	bool IsBillboardGeom() const { return isBillboardGeom; }
	bool IsTerrainGeom() const { return isTerrainGeom; }

	// Calculates the BBox of the parent
	void CalculateBBox();
	void CalculateBBoxOctree();

	// Rotates the vertices
	virtual void Rotate(const D3DXMATRIX *rotation);

protected:

	// Mesh data
	Mesh mesh;

	// Parent Entity
	Entity *parent;

	// Texture pointer to load
	Texture *texture;

	// Type of Geometry
	bool isSubdivisionGeom : 1;
	bool isBillboardGeom : 1;
	bool isTerrainGeom : 1;

	// Updates the Normals array
	#define NORMAL_MODIFIER 0.3f
	virtual void AddNormals();

	// Draws a grid for a specified mesh
	void _DrawGrid(Mesh *m, uint width, uint height, float size = 1.0f, const Real3 &center = Real3(0.0f, 0.0f, 0.0f));

	// Renders geometry specific
	virtual void _Render(uchar renderFlag) =  0;
};

#endif // __GEOMETRY_H__